home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Communication
/
Weather
/
Source
/
ColorBars.m
< prev
next >
Wrap
Text File
|
1993-11-14
|
8KB
|
322 lines
/*
* Magic Media Lab Colorbars, from the Media Lab letterhead,
* with some animation tricks. c.f. License.m for an example of use.
*/
/*
Copyright (c) 1991, 1992 by the MIT Media Laboratory
This software is distributed by Michael Hawley of the MIT Media Laboratory.
We hope it will be useful to you.
Permission to use, copy, or modify this software for educational
and research purposes only and without fee is hereby granted
provided this notice appears on all copies, and provided you send
us your improvements. Any other use of this software, in original
or modified form, in whole or in part, requires specific permission
from MIT. This software shall not be used, rewritten, or adapted
for use in a commercial product without first obtaining appropriate
licenses from MIT. MIT makes no representations about the suitability
of this software for any purpose: it is provided "as is" without any
warranty and any risk, damage, or liability incurred through your use
of this software is yours alone.
Michael Hawley
MIT Media Laboratory
20 Ames Street,
Cambridge, MA 02139
mike@media-lab.mit.edu
*/
#import "ColorBars.h"
@implementation ColorBars
#define N 8
static float pct[N] = { 0.0790, 0.1535, 0.0564, 0.2279, 0.0745,
0.2596, .1083, .0406};
static NXColor color[N];
static void
initColors(){
int i = 0;
#define C(r,g,b) color[i++] = NXConvertRGBToColor(r/256.0, g/256.0, b/256.0);
C(77.0,17.0,93.0)
C(0.0,85.0,0.0)
C(255.0,255.0,255.0)
C(210.0,0.0,0.0)
C(255.0,90.0,0.0)
C(0.0,0.0,151.0)
C(255.0,248.0,0.0)
C(85.0,85.0,85.0)
}
- initFrame:(const NXRect *)r {
[super initFrame:r];
backgroundColor = NX_COLORWHITE;
delay = .25;
initColors();
return self;
}
static void
drawColors(c,R) NXColor *c; NXRect R; {
int i;
NXCoord w = R.size.width;
NXRect r;
r = R;
r.size.width = w * pct[0];
for (i=0; i<N; i++, r.size.width = w * pct[i]){
NXSetColor(c[i]);
NXRectFill(&r);
r.origin.x += r.size.width;
}
}
- drawColors:(NXColor *)c{
drawColors(c,bounds);
return self;
}
- (int)running { return running; }
static NXColor
fade(i,n,c1,c2)
int i, n;
NXColor c1, c2;
/* return a color that's i/n of the way from c1->c2 in RGB */
{
float r1, g1, b1, r2, g2, b2;
float p = (float)(i)/(float)(n-1);
NXConvertColorToRGB(c1,&r1,&g1,&b1);
NXConvertColorToRGB(c2,&r2,&g2,&b2);
#define mix(a,b) (a-p*(a-b))
r1 = mix(r1,r2); g1 = mix(g1,g2); b1 = mix(b1,b2);
c1 = NXConvertRGBToColor(r1,g1,b1);
return c1;
}
- fill:(NXColor)c {
NXSetColor(c);
NXRectFill(&bounds);
return self;
}
- stopIt {
running = 0;
return self;
}
- (NXColor)backgroundColor { return backgroundColor; }
- setBackgroundColor:(NXColor)c {
backgroundColor = c;
return self;
}
static void
swabScramble(n) int n[N]; {
int k=0,r,t[N] = {0,1,2,3,4,5,6,7};
#define pick(t,n) t[r=random()%n]
#define skip(t,n) { int i,j=0; for (i=0;i<N;i++){ t[j] = t[i]; if (t[j] != n) j++; } }
for (k=0;k<N;k++) n[k] = -1;
k = 0;
skip(t,k);
n[k] = pick(t,7);
skip(t,n[k]);
n[n[k]] = k;
while (n[k] != -1 && k < N) k++;
skip(t,k);
n[k] = pick(t,5);
skip(t,n[k]);
n[n[k]] = k;
while (n[k] != -1 && k < N) k++;
skip(t,k);
n[k] = pick(t,3);
skip(t,n[k]);
n[n[k]] = k;
while (n[k] != -1 && k < N) k++;
skip(t,k);
n[k] = pick(t,1);
skip(t,n[k]);
n[n[k]] = k;
while (n[k] != -1 && k < N) k++;
}
static void
swabStep(DPSTimedEntry te, double timeNow, id self)
/*
* Interpolate between pairs of segments
*/
{
static int i = 0, f = 0;
int j;
static NXColor pc[N], cc[N];
NXColor c[N];
#define M 48
if (i==0){ /* pick random pairs of colors */
int n[8];
if (f==0){
f = 1;
for (j=0;j<N;j++){
pc[j] = [self backgroundColor];
cc[j] = color[j];
}
} else {
if (f%3 == 0){
for (j=0;j<N;j++) cc[j] = color[j];
} else {
swabScramble(n);
for (j=0;j<N;j++) cc[j] = pc[n[j]];
}
}
}
for (j=0;j<N;j++) c[j] = fade(i,M,pc[j],cc[j]);
[self lockFocus];
[self drawColors:c];
i++;
if (i==M || ![self running]){
i = 0;
if (![self running] && te) DPSRemoveTimedEntry(te);
for (j=0;j<N;j++) pc[j] = cc[j];
f++;
}
[self unlockFocus];
[[self window] flushWindow]; NXPing();
}
static void
fadeStep(DPSTimedEntry te, double timeNow, id self) {
static int i = 0;
int j;
NXColor c[N];
#undef M
#define M 64
for (j=0;j<N;j++) c[j] = fade(i,M,[self backgroundColor],color[j]);
[self lockFocus];
[self drawColors:c];
i++;
if (i==M || ![self running]){
i = 0;
if (te) DPSRemoveTimedEntry(te);
[self stopIt];
}
[self unlockFocus];
[[self window] flushWindow]; NXPing();
}
- fadeOn {
running = 1;
while (running) fadeStep(0,0.,self), usleep(2500);
return self;
}
static void
scramble(n) int *n; {
int i, k, l;
for (i=0; i<N; i++) n[i] = i;
for (i=0; i<N; i++){
k = random()%N;
l = n[k];
n[k] = n[i];
n[i] = l;
}
}
static void
scrambleStep(DPSTimedEntry te, double timeNow, id self) {
static int skip = 0;
int cn[N], j;
NXColor c[N];
if (skip > 0) { skip--; return; }
[self lockFocus];
if (random()%8 == 3){
[self drawColors:color];
skip = 3;
} else {
scramble(cn);
for (j=0;j<N;j++) c[j] = color[cn[j]];
[self drawColors:c];
if (![self running]){
DPSRemoveTimedEntry(te);
[self stopIt];
}
}
[self unlockFocus];
[[self window] flushWindow]; NXPing();
}
- winkOff {
NXRect r, a, b;
r = a = b = bounds;
drawColors(color,bounds); [window flushWindow]; NXPing();
NXSetColor(backgroundColor);
a.size.height = b.size.height = 1;
a.origin.y = r.origin.y + r.size.height;
while (a.origin.y > b.origin.y){
NXRectFill(&a); NXRectFill(&b);
a.origin.y -= 1;
b.origin.y += 1;
usleep(30000);
[window flushWindow]; NXPing();
}
a.origin.y += 1;
b.origin.y -= 1;
r = b; r.size.height = a.origin.y - b.origin.y;
while (r.size.width > 2){
NXSetColor(backgroundColor); NXRectFill(&r);
r.origin.x += 2; r.size.width -= 4;
drawColors(color,r); [window flushWindow]; NXPing();
}
r.size.width = 1;
NXSetColor(NXConvertRGBToColor(.05,.05,.05)); NXRectFill(&r);
[window flushWindow]; NXPing();
usleep(1000000);
NXSetColor(backgroundColor); NXRectFill(&r);
[window flushWindow]; NXPing();
usleep(300000);
return self;
}
- setDrawstyle:(int)n {
style = n;
return [self display];
}
- animate:(void (*)())f{
if (!running)
running++, DPSAddTimedEntry(0.025, f, self,100);
return self;
}
- animate:(void (*)())f :(float)t{
if (!running)
running++, DPSAddTimedEntry(t, f, self,100);
return self;
}
- drawSelf:(const NXRect *)rects :(int)n {
switch (style){
case PLAIN: return [self drawColors:color];
case FADE: return [self animate:fadeStep];
case SWAB: return [self animate:swabStep];
case SCRAMBLE: return [self animate:scrambleStep:delay];
case FSCRAMBLE: [self fadeOn];
usleep(1000000);
return [self animate:scrambleStep:delay];
case CLEAR: return [self fill:backgroundColor];
case WINKOFF: return [self winkOff];
}
return self;
}
@end